package admin.iss.nus.edu.sg;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.amazonaws.services.dynamodb.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodb.model.AttributeValue;
import com.amazonaws.services.dynamodb.model.ComparisonOperator;
import com.amazonaws.services.dynamodb.model.Condition;
import com.amazonaws.services.dynamodb.model.DeleteItemRequest;
import com.amazonaws.services.dynamodb.model.DeleteItemResult;
import com.amazonaws.services.dynamodb.model.Key;
import com.amazonaws.services.dynamodb.model.PutItemRequest;
import com.amazonaws.services.dynamodb.model.PutItemResult;
import com.amazonaws.services.dynamodb.model.QueryRequest;
import com.amazonaws.services.dynamodb.model.QueryResult;
import com.amazonaws.services.dynamodb.model.ScanRequest;
import com.amazonaws.services.dynamodb.model.ScanResult;

import sg.edu.nus.iss.CONFIG;
import sg.edu.nus.iss.Util;
import sg.edu.nus.iss.stockex.RelativeStrengthIndex;
import sg.edu.nus.iss.stockex.StochasticOscillator;

public class StochasticOscillatorTable implements DynamoDBTableInf<StochasticOscillator> {
	private AmazonDynamoDBClient dynamoDB = DynamoDB.client();
	
	
	@Override
	public Map<String, AttributeValue> newItem(StochasticOscillator item) {
		Map<String, AttributeValue> map = new HashMap<String, AttributeValue>();
		map.put("code", new AttributeValue(item.getCode()));
		map.put("value", new AttributeValue().withN(Double.toString(item.getValue())));
		map.put("date", new AttributeValue(item.getDate()));
		return map;
	}

	@Override
	public boolean Add(StochasticOscillator item) {
		 boolean status = false;
		 try{
		 Map<String,AttributeValue> map = newItem(item);
		 PutItemRequest putItemRequest = new PutItemRequest(CONFIG.STOCHASTIC_OSCILLATOR_TABLE_NAME, map);
		 PutItemResult putItemResult = dynamoDB.putItem(putItemRequest);
		 System.out.println("Result: " + putItemResult);
		 if(putItemResult!=null)
		 {
			 status =  true;
		 }
		 }catch (Exception e) {
			 e.printStackTrace();
			// TODO: handle exception
		}
		
		 return status;
	}

	@Override
	public boolean Delete(StochasticOscillator item) {
		boolean status = false;
		Key key = new Key();
		key.setHashKeyElement(new AttributeValue(item.getCode()));
		key.setRangeKeyElement(new AttributeValue(item.getDate()));
		try{
			DeleteItemRequest deleteItemRequest = new DeleteItemRequest().withTableName(CONFIG.STOCHASTIC_OSCILLATOR_TABLE_NAME).withKey(key);
			DeleteItemResult result = dynamoDB.deleteItem(deleteItemRequest);
			if(result!=null)
			{
				status = true;	
			}
		}catch (Exception e) {
			// TODO: handle exception
		}
		return status;
	}
	
	public ArrayList<StochasticOscillator> listItems(String date)
	{
		DynamoDB.waitForTableToBecomeAvailable(CONFIG.STOCHASTIC_OSCILLATOR_TABLE_NAME);
    	ArrayList<StochasticOscillator> SOList = new ArrayList<StochasticOscillator>();
        HashMap<String, Condition> scanFilter = new HashMap<String, Condition>();
        Condition condition = new Condition()
            .withComparisonOperator(ComparisonOperator.GT.toString())
            .withAttributeValueList(new AttributeValue(date));
        scanFilter.put("date", condition);
        ScanRequest scanRequest = new ScanRequest(CONFIG.STOCHASTIC_OSCILLATOR_TABLE_NAME).withScanFilter(scanFilter);
        ScanResult scanResult = dynamoDB.scan(scanRequest);
       
        List<Map<String,AttributeValue>> SOMapList  = scanResult.getItems();
        System.out.println("quoteMapList:"+SOMapList.size());
        String codeStr = "";
        StochasticOscillator SOObj = null;
        AttributeValue attr = new AttributeValue();
        System.out.println("Dispalying all the data....");
        for (Map<String, AttributeValue> map : SOMapList) {
        	SOObj.setCode(map.get("code").getS());
        	SOObj.setDate(map.get("date").getS());
        	SOObj.setValue(new Double(map.get("value").getN()).doubleValue());
        	if(SOObj!=null)
        	{
        		SOList.add(SOObj);
        	}
		}
        return SOList;
	}

	//past 30 days based on code and date..
	public ArrayList<StochasticOscillator> query(String code, String date)
	{
		ArrayList<StochasticOscillator> rsiList = new ArrayList<StochasticOscillator>();
		String backDate = Util.oneMonthBackDate(date);
		
		Condition rangeKeyCondition = new Condition()
		.withComparisonOperator(ComparisonOperator.BETWEEN.toString())
		.withAttributeValueList(new AttributeValue().withS(backDate), new AttributeValue().withS(date));
		
		QueryRequest queryRequest = new QueryRequest().withTableName(CONFIG.STOCHASTIC_OSCILLATOR_TABLE_NAME)
				.withHashKeyValue(new AttributeValue().withS(code))
				.withRangeKeyCondition(rangeKeyCondition);
		QueryResult result = dynamoDB.query(queryRequest);
		for (Map<String, AttributeValue> item : result.getItems()) {
			rsiList.add(convert(item));
		}
		return rsiList;
	}
	
	public StochasticOscillator convert(Map<String, AttributeValue> item)
	{
		StochasticOscillator so = null;
		String code = item.get("code").getS();
		String date = item.get("date").getS();
		
		double soValue = new Double(item.get("value").getN()).doubleValue();
		so = new StochasticOscillator(code, date, soValue);
		return so;
	}
}
